package gateway

import (
	"gitee.com/JMArch/rpcmon-gateway/conf"
	"gitee.com/JMArch/rpcmon-gateway/httpsrv"
	"gitee.com/JMArch/rpcmon-gateway/log"
	"gitee.com/JMArch/rpcmon-gateway/owl"
	"gitee.com/JMArch/rpcmon-gateway/rpcmon"
	"gitee.com/JMArch/rpcmon-gateway/storage"
	"go.uber.org/zap"
)

type GatewayServer struct {
	Log        *log.GatewayLog
	Service    *httpsrv.HttpSrv
	RPCBackend *rpcmon.ClientGroup
	OWLBackend *owl.ClientGroup
	Storage    *storage.CacheGroup
}

func New(file string) (*GatewayServer, error) {

	config, err := conf.New(file)
	if err != nil {
		return nil, err
	}

	logger, err := log.New(config.LogFile, config.LogLevel)
	if err != nil {
		return nil, err
	}

	cacheGroup := storage.NewCacheGroup(config, logger)
	logger.Info("start cache")

	service := httpsrv.New(cacheGroup, config, logger)
	logger.Info("start http service")

	r, err := rpcmon.NewClientGroup(cacheGroup, config, logger)
	if err != nil {
		logger.Error("start rpcmon client fail", zap.Error(err))
		return nil, err
	}
	logger.Info("start rpcmon client")

	o, err := owl.NewClientGroup(cacheGroup, config, logger)
	if err != nil {
		logger.Error("start owl client fail", zap.Error(err))
		return nil, err
	}
	logger.Info("start owl client")

	gserver := &GatewayServer{
		Log:        logger,
		Service:    service,
		Storage:    cacheGroup,
		RPCBackend: r,
		OWLBackend: o,
	}

	return gserver, nil
}

func (g *GatewayServer) Run() {
	g.Service.Serve()
}

func (g *GatewayServer) Close() {
	g.Log.Info("stop service")
	g.Service.Close()
	g.Log.Info("stop storage")
	g.Storage.Close()
	g.Log.Info("stop rpc")
	g.RPCBackend.Close()
	g.Log.Info("stop backend")
	g.OWLBackend.Close()
}
